package com.kinyx.framework.bean;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;

import com.kinyx.framework.annotation.assist.CanNull;
import com.kinyx.framework.annotation.assist.Note;
import com.kinyx.framework.annotation.assist.ReturnNotNull;
import com.kinyx.framework.annotation.assist.ReturnNull;
import com.kinyx.framework.annotation.assist.Tester;
import com.kinyx.framework.utils.KListUtils;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;

/**
 * 键值对
 */
@Tester("com.kinyx.framework.bean.KeyValus_Tester_")
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class KeyValues {

	// ===================================================== field ===================================================== //
	/** 内置集合对象 */
	private final Map<String, List<String>> map = new HashMap<>();

	// ===================================================== construct ===================================================== //
	/**
	 * 构造方法
	 * @return 新对象
	 */
	public static KeyValues of() { return new KeyValues(); }

	// ===================================================== method ===================================================== //
	/**
	 * 清空数据
	 * @return 本对象
	 */
	@ReturnNotNull
	@Note("return this;")
	public KeyValues clear() {
		this.map.clear();
		return this;
	}

	/**
	 * 追加值
	 * @param key 键
	 * @param value 值
	 * @return 本对象
	 */
	@ReturnNotNull
	@Note("return this;")
	public KeyValues add(@CanNull final String key, @CanNull final String value) {
		List<String> list = this.map.get(key);
		if (list == null) {
			list = new ArrayList<>();
			this.map.put(key, list);
		}
		list.add(value);
		return this;
	}

	/**
	 * 获取值
	 * @param key 键
	 * @param separator 分隔符
	 * @param converter 转换器
	 * @return 拼接结果
	 */
	@ReturnNull("未存储过该值")
	public String get(@CanNull final String key, @CanNull(defaultValue = ",") final String separator, @CanNull(defaultValue = "toString()") final BiFunction<String, Integer, String> converter) {
		return KListUtils.join(this.map.get(key), separator, converter);
	}

}
